import {
  Injectable,
  NestInterceptor,
  CallHandler,
  ExecutionContext,
} from "@nestjs/common";
import { map } from "rxjs/operators";
import { Observable } from "rxjs";
import * as Log4js from "log4js";
import config from "@/config/log4.config";
import { LogService } from "@/modules/system/log/log.service";
import { LogDto } from "@/modules/system/log/dto/log.dto";
import { ResponseResult } from "../tools/response.result";

@Injectable()
export class LoggerInterceptor implements NestInterceptor {
  constructor(private readonly logService: LogService) {
    Log4js.configure(config);
  }
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const start = Date.now();
    const req = context.getArgByIndex(1).req;
    const logData = {
      type: 0,
      ip: req.headers?.remoteip
        ? String(req.headers.remoteip)
        : req.ip.split(":").pop(),
      operateId: "admin",
      request: JSON.stringify({
        url: req.url,
        method: req.method,
        query: req.query,
        params: req.params,
        body: req.body,
      }),
    };

    return next.handle().pipe(
      map((data) => {
        const result = new ResponseResult(0, "操作成功", data ?? null);
        const end = Date.now();
        const logObj = {
          ...logData,
          response: JSON.stringify(result),
          duration: end - start,
          operateId: "admin",
        };

        const logger = Log4js.getLogger("info");
        logger.info(logObj);
        if (!req.url.includes("/system/logs")) {
          const logDto = new LogDto();
          logDto.type = 0;
          logDto.ip = logObj.ip;
          logDto.request = logObj.request;
          logDto.response = logObj.response;
          logDto.duration = logObj.duration;
          logDto.operateId = logObj.operateId;
          this.logService.createLog(req.headers["tenant-id"], logDto);
        }
        return data;
      })
    );
  }
}
